/*
 * Copyright Kulikov Victor 2009
 * Distributed under LGPL license

 * Modified by Pavel Shchelkun 2012
 * in his part of a diploma project
 * named DVGEditor <http://code.google.com/p/dataviewer/>
 * and  distributed under GNU GPL license.
 */
#ifndef POLYGONTOOL_H
#define POLYGONTOOL_H
#include <QApplication>
#include <QGraphicsItem>
#include <QGraphicsPolygonItem>
#include <QPainter>
#include <QSet>
#include <QMenu>
#include "types.h"

/*!
  That class represent a node of polygonal tool that can make transforms on Graphics Item objects.
  */

class QTextStream;

class PolygonTool : public QGraphicsItem
{
    Q_DECLARE_TR_FUNCTIONS(PolygonTool)
public:
    PolygonTool(int number,QGraphicsPolygonItem* poly);
    ~PolygonTool();
    //Overiden functions from QGraphicsItem
    QRectF boundingRect() const;
    QPainterPath shape() const;
    void paint(QPainter *painter,
               const QStyleOptionGraphicsItem *option, QWidget *widget);
    //Set the pointer of the object we want to transform
    void setTransformObject(QGraphicsItem* item);

    //Some static function for creation of polygons
    static QList<PolygonTool*> createFromPolygon(QGraphicsPolygonItem* poly);
    static QList<PolygonTool*> createFromPolygon(QGraphicsPolygonItem* poly,QGraphicsItem *obj);

    static bool isTool(QGraphicsItem* item);
    static bool isConvex(QPolygonF poly);

    static void hideAll();
    static void showAll();

    inline void setNumber(int i){ m_number = i; }
    inline int  getNumber(){ return m_number; }

protected:
    static QSet<QGraphicsItem*> tools;
    QRectF outlineRect() const;
    //Function when the magic begins:)
    QVariant itemChange(GraphicsItemChange change,
                        const QVariant &value);
    //Pointer to resizing object
    QGraphicsItem* m_transobj;
    //id of node in polygon
    int m_number;
    //Polygon holder
    QGraphicsPolygonItem* m_poly;
    //--------------------

    void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
    QMenu   *m_pToolContextMenu;
public:
    inline void setToolContextMenu(QMenu *menu){ m_pToolContextMenu = menu; }
};

/*!Class for polygon witch is used to resize objects or to work with polygon forms*/
class MagicPolygon: public QGraphicsPolygonItem
{
  public:
    MagicPolygon(int uid, QGraphicsItem *obj);
    ~MagicPolygon();

    inline void setContextMenu(QMenu *menu){ m_pContextMenu = menu; }
    void setToolContextMenu(QMenu *menu);
    /*!
      Hide polygon and his nodes
      */
    void hide();
    void hideTools();
    /*!
      Show polygon and his nodes
      */
    void show();
    /*!
      Redefined function for setting polygon
      */
    void setPolygon(const QPolygonF &polygon);
    void paint(QPainter *painter,
               const QStyleOptionGraphicsItem *option, QWidget *widget);
    /*!
      Redefined function setPen to object if object has one, setPen to the polygon otherwise
      */
    void setPen(const QPen &pen);
    /*!
      Redefined function setBrush to object if object has one, setBrush to the polygon otherwise
      */
    void setBrush(const QBrush &brush);
    /*!
        That function draw the item of the polygon white if layerid==m_layerid else it draw it transparent
      */
    void setBinaryMode(bool flag,int layerid);
    /*!
      Set id of item layed for render
      */
    void setLayerId(int id);
    void writeToStream(QDataStream *out);
    void readFromStream(QDataStream* in);
    bool saveObject(QTextStream *out);
    bool loadObject(QDomNode node);
    //-------------------------------
    void RemoveNode();
    void DuplicateNode();
    //-------------------------------
   protected:
    void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
    QVariant itemChange(GraphicsItemChange change,
                        const QVariant &value);
    //Old position of object used for parent-child mechanism
    QPointF oldpos;
    //Object assosiated with the polygon if it is NULL so rectang is send alone primitive
    QGraphicsItem* m_object;
    //List of child nodes for resizing
    QList<PolygonTool*> m_tools;

    //Normal draw properties
    QPen m_pen;
    QBrush m_brush;

    //Used when the polygon in binary mode
    QBrush m_membrush;
    QPen m_mempen;
    //------------------------------------------
    QMenu   *m_pContextMenu;
    QMenu   *m_pToolContextMenu;
    //layer id
    int m_layerid;
    // is empty polygon;
    bool m_isEmpty;
public:
    inline bool isEmpty(){ return m_isEmpty; }
    inline void    setName(const QString& name){ setData(POLYGON_NAME,QVariant(name)); }
    inline QString getName(){ return data(POLYGON_NAME).toString(); }
};

#endif // POLYGONTOOL_H
